package com.qianbao.qianbaobusiness.ui.start;

import android.support.annotation.NonNull;

import com.androidbase.base.mvp.RxMvpPresenter;
import com.androidbase.download.DownloadException;
import com.androidbase.download.DownloadManager;
import com.androidbase.download.downinterfaceimpl.SimpleDownLoadCallBack;
import com.androidbase.utils.RxUtils;
import com.baseandroid.config.Constant;
import com.baseandroid.config.Global;
import com.baseandroid.config.MyApi;
import com.baseandroid.retrofit.RxObserver;
import com.baseandroid.retrofit.json.Data;
import com.qianbao.qianbaobusiness.json.CheckUpdate;
import com.qianbao.qianbaobusiness.json.ServerTime;
import com.qianbao.qianbaobusiness.json.ShopListInfo;
import com.qianbao.qianbaobusiness.json.UserInfo;
import com.qianbao.qianbaobusiness.json.UserTokenInfo;

import java.io.File;
import java.util.HashMap;

import javax.inject.Inject;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.functions.Function;

public class StartPresent extends RxMvpPresenter<StartView> {

    public final static int SERVER_DATE_NORMAL = 0x1000;
    public final static int SERVER_DATE_EXCEPTION = 0x1001;
    public final static int SERVER_TIME_EXPIRE = 0x1002;
    public final static int SERVER_TIME_NOT_EXPIRE = 0x1003;

    MyApi mMyApi;

    @Inject
    public StartPresent(MyApi myApi) {
        mMyApi = myApi;
    }

    public void checkUpdate() {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("classcode", Constant.ANDROIDVERSION);

        mMyApi.checkUpdate(hashMap)
                .compose(RxUtils.<Data<CheckUpdate>>applySchedulersLifeCycle(getView()))
                .subscribe(new RxObserver<Data<CheckUpdate>>() {

                    @Override
                    public void onNext(@NonNull Data<CheckUpdate> checkUpdateData) {
                        if (RxObserver.checkJsonCode(checkUpdateData, true)) {
                            getView().OnVersionUpdate(checkUpdateData.getResult());
                        } else {
                            getView().OnVersionUpdateError();
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        getView().OnVersionUpdateError();
                    }
                });
    }

    public void requestDownload(String sUpdateUrl, String downLoadApkFolde, String downLoadApkFileName) {
        DownloadManager.getInstance()
                .download(sUpdateUrl, new File(downLoadApkFolde), downLoadApkFileName, false, new SimpleDownLoadCallBack() {

                    @Override
                    public void onProgress(long finished, long total, int progress) {
                        if (getView() != null) {
                            getView().downloadProgress(progress);
                        }
                    }

                    @Override
                    public void onCompleted(File downloadfile) {
                        if (getView() != null) {
                            getView().downloadCompleted();
                        }
                    }

                    @Override
                    public void onFailed(DownloadException e) {
                        if (getView() != null) {
                            getView().downloadFailed();
                        }
                    }
                });
    }

    public Observable<Data<ServerTime>> getServiceTime() {
        return mMyApi.getServerTime();
    }

    public Observable<Data<UserTokenInfo>> refreshToken() {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("rf_token", Global.getUserTokenInfo().getRf_token());
        return mMyApi.refreshToken(hashMap);
    }

    public Observable<Data<UserInfo>> getUserInfo() {
        return mMyApi.getUserinfo();
    }

    public Observable<Data<ShopListInfo>> getUserShopListInfo() {
        return mMyApi.getUserShopListInfo();
    }


    public void requestUserInfo() {
        getServiceTime().map(new Function<Data<ServerTime>, Integer>() {
            @Override
            public Integer apply(@NonNull Data<ServerTime> serverTimeData) throws
                    Exception {
                return doneServiceTime(serverTimeData);
            }
        })
                .flatMap(new Function<Integer, Observable<Integer>>() {
                    @Override
                    public Observable<Integer> apply(@NonNull Integer integer) throws
                            Exception {
                        return doneRefreshToken(integer);
                    }
                })
                .flatMap(new Function<Integer, Observable<Integer>>() {
                    @Override
                    public Observable<Integer> apply(@NonNull Integer integer) throws
                            Exception {
                        return doneuseInfo(integer);
                    }
                })
                .flatMap(new Function<Integer, Observable<Integer>>() {
                    @Override
                    public Observable<Integer> apply(Integer integer) throws Exception {
                        return doneuseShoplisInfo(integer);
                    }
                })
                .compose(RxUtils.<Integer>applySchedulersLifeCycle(getView()))
                .subscribe(new RxObserver<Integer>() {

                    @Override
                    public void onNext(@NonNull Integer integer) {
                        if (integer == SERVER_DATE_NORMAL) {
                            getView().OnUserInfoSuccess();
                        } else {
                            getView().OnUserInfoError();
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        getView().OnUserInfoError();
                    }
                });
    }

    private Integer doneServiceTime(@NonNull Data<ServerTime> serverTimeData) {
        if (RxObserver.checkJsonCode(serverTimeData, false)) {
            long curentTime = Long.parseLong(serverTimeData.getResult()
                    .getCurrent_server_time());
            long expirTime = 0;
            if (Global.getUserTokenInfo().getToken_expire_at() != null) {
                expirTime = Long.parseLong(Global.getUserTokenInfo()
                        .getToken_expire_at());
            }

            if (curentTime + 24 * 3 * Constant.TIME_ONE_HOUR / 1000 > expirTime) {
                return SERVER_TIME_EXPIRE;
            }

            return SERVER_TIME_NOT_EXPIRE;
        }
        return SERVER_DATE_EXCEPTION;
    }

    private Observable<Integer> doneRefreshToken(@NonNull Integer integer) {
        if (integer == SERVER_TIME_EXPIRE) {
            return refreshToken().map(new Function<Data<UserTokenInfo>, Integer>() {
                @Override
                public Integer apply(@NonNull Data<UserTokenInfo> userTokenInfoData) throws
                        Exception {
                    if (RxObserver.checkJsonCode(userTokenInfoData, false)) {
                        Global.setUserTokenInfo(userTokenInfoData.getResult());
                        return SERVER_DATE_NORMAL;
                    }

                    return SERVER_DATE_EXCEPTION;
                }
            });
        } else if (integer == SERVER_TIME_NOT_EXPIRE) {
            return Observable.create(new ObservableOnSubscribe<Integer>() {

                @Override
                public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws
                        Exception {
                    emitter.onNext(SERVER_DATE_NORMAL);
                    emitter.onComplete();

                }
            });
        }

        return Observable.create(new ObservableOnSubscribe<Integer>() {

            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws
                    Exception {
                emitter.onNext(SERVER_DATE_EXCEPTION);
                emitter.onComplete();
            }
        });
    }

    private Observable<Integer> doneuseInfo(@NonNull Integer integer) {
        if (integer == SERVER_DATE_NORMAL) {
            return getUserInfo().map(new Function<Data<UserInfo>, Integer>() {
                @Override
                public Integer apply(@NonNull Data<UserInfo> userInfoData) throws
                        Exception {
                    if (RxObserver.checkJsonCode(userInfoData, false)) {
                        Global.setUserInfoBean(userInfoData.getResult());
                        return SERVER_DATE_NORMAL;
                    }

                    return SERVER_DATE_EXCEPTION;
                }
            });
        }

        return Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws
                    Exception {
                emitter.onNext(SERVER_DATE_EXCEPTION);
                emitter.onComplete();
            }
        });
    }

    private Observable<Integer> doneuseShoplisInfo(@NonNull Integer integer) {
        if (integer == SERVER_DATE_NORMAL) {
            return getUserShopListInfo().map(new Function<Data<ShopListInfo>, Integer>() {
                @Override
                public Integer apply(@NonNull Data<ShopListInfo> shopListInfoData) throws
                        Exception {
                    if (RxObserver.checkJsonCode(shopListInfoData, false)) {
                        Global.setShopListInfo(shopListInfoData.getResult());
                        return SERVER_DATE_NORMAL;
                    }

                    return SERVER_DATE_EXCEPTION;
                }
            });
        }

        return Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws
                    Exception {
                emitter.onNext(SERVER_DATE_EXCEPTION);
                emitter.onComplete();
            }
        });
    }

}
